#include "protreewidget.h"
#include <QDir>
#include "protreeitem.h"
#include "const.h"
#include <QDebug>
#include <QHeaderView>
#include <QGuiApplication>
#include <QMenu>
#include <QFileDialog>
#include "removeprodialog.h"
#include "slideshowdlg.h"

ProTreeWidget::ProTreeWidget(QWidget *parent)
    : QTreeWidget(parent), _active_item(nullptr), _right_btn_item(nullptr),_selected_item(nullptr),
    _dialog_progress(nullptr), _thread_create_pro(nullptr), _thread_open_pro(nullptr),_open_progressdlg(nullptr)
{
    this->header()->hide();     // 把头隐藏
    connect(this, &ProTreeWidget::itemPressed, this, &ProTreeWidget::SlotItemPressed);
    _action_import = new QAction(QIcon(":/icon/import.png"), tr("导入文件"), this);
    _action_setstart = new QAction(QIcon(":/icon/core.png"), tr("设置活动项目"), this);
    _action_closepro = new QAction(QIcon(":/icon/close.png"), tr("关闭项目"), this);
    _action_slideshow = new QAction(QIcon(":/icon/SlideShow.png"), tr("轮播图播放"), this);

    connect(_action_import, &QAction::triggered, this, &ProTreeWidget::SlotImport);             // 导入文件
    connect(_action_setstart, &QAction::triggered, this, &ProTreeWidget::SlotSetActive);      //  设置活动项
    connect(_action_closepro, &QAction::triggered, this, &ProTreeWidget::SlotClosePro);       // 关闭项目
    connect(this, &ProTreeWidget::itemDoubleClicked, this, &ProTreeWidget::SlotDoubleClickItem);
    connect(_action_slideshow, &QAction::triggered, this, &ProTreeWidget::SlotSlideShow);

    _player = new QMediaPlayer(this);
    _playlist = new QMediaPlaylist(this);
    _playlist->setPlaybackMode(QMediaPlaylist::Loop);
    _player->setPlaylist(_playlist);
}

void ProTreeWidget::AddProToTree(const QString &name, const QString &path)
{
    QDir dir(path);     // 创建一个文件夹
    QString file_path = dir.absoluteFilePath(name);
    if(_set_path.find(file_path) != _set_path.end()){       // 不等于 end，表明找到了重名，返回空
        return ;
    }

    QDir pro_dir(file_path);
    if(!pro_dir.exists()){
        bool enable = pro_dir.mkpath(file_path);
        if(!enable){
            return ;
        }
    }

    qDebug() << "...................." << endl;
    _set_path.insert(file_path);
    auto *item = new ProTreeItem(this, name, file_path, TreeItemPro);
    item->setData(0, Qt::DisplayRole, name);
    item->setData(0, Qt::DecorationRole, QIcon(":/icon/direction.png"));
    item->setData(0, Qt::ToolTipRole, file_path);       // 鼠标悬浮时显示文件路径
    this->addTopLevelItem(item);
}

void ProTreeWidget::SlotItemPressed(QTreeWidgetItem *pressedItem, int column)
{
    // qDebug()  <<  "SlotItemPressed"   << endl;
    if(QGuiApplication::mouseButtons() == Qt::RightButton){
        QMenu menu(this);
        int itemtype = pressedItem->type();
        if(itemtype == TreeItemPro){
            _right_btn_item = pressedItem;
            // 为菜单添加动作
            menu.addAction(_action_import);
            menu.addAction(_action_setstart);
            menu.addAction(_action_closepro);
            menu.addAction(_action_slideshow);
            menu.exec(QCursor::pos());  // 在鼠标右键的位置执行
        }
    }
}

void ProTreeWidget::SlotImport()
{
    QFileDialog file_dialog;
    file_dialog.setFileMode(QFileDialog::Directory);
    file_dialog.setWindowTitle(tr("选择导入的文件夹"));
    QString path = "";
    if(!_right_btn_item){       // 判断右键点击状态
        qDebug() << "_right_btn_item is empty" << endl;
        return ;
    }

    path = dynamic_cast<ProTreeItem*>(_right_btn_item)->GetPath();      // 动态转换后再调用获取路径的函数
    file_dialog.setDirectory(path);
    file_dialog.setViewMode(QFileDialog::Detail);

    QStringList fileNames;      // 存储用户选定的文件路径列表
    if(file_dialog.exec()){
        fileNames = file_dialog.selectedFiles();        // selectedFiles() 方法返回一个 QStringList，其中包含了用户在文件对话框中选定的所有文件的路径
    }

    if(fileNames.length() <= 0){
        return ;
    }

    QString import_path = fileNames.at(0);
    int file_count = 0;
    _dialog_progress = new QProgressDialog(this);

    // 创建线程
    _thread_create_pro = std::make_shared<ProTreeThread>(std::ref(import_path), std::ref(path), _right_btn_item,
                                                         std::ref(file_count), this, _right_btn_item, nullptr);
    // 连接线程的信号域槽
    connect(_thread_create_pro.get(), &ProTreeThread::SigUpdateProgress, this, &ProTreeWidget::SlotUpdateProgress);   // 使用智能指针时需用get()方法取出真实类型

    connect(_thread_create_pro.get(), &ProTreeThread::SigFinishProgress, this, &ProTreeWidget::SlotFinishProgress);

    connect(_dialog_progress, &QProgressDialog::canceled, this ,&ProTreeWidget::SlotCancelProgress);

    connect(this, &ProTreeWidget::SigCancelProgress, _thread_create_pro.get(), &ProTreeThread::SlotCancelProgress);     // 通过线程

    _thread_create_pro->start();        // 启动线程
    qDebug() << " _thread_create_pro->start();";
    _dialog_progress->setWindowTitle("Please wait......");
    _dialog_progress->setFixedWidth(PROGRESS_WIDTH);        // 固定为PROGRESS_WIDTH（300）
    _dialog_progress->setRange(0,PROGRESS_WIDTH);       // 波动范围
    _dialog_progress->exec();


}

void ProTreeWidget::SlotSetActive()
{
    if(!_right_btn_item){
        return ;
    }

    QFont nullFont;
    nullFont.setBold(false);        // 设置为非粗体

    if(_active_item){
        _active_item->setFont(0,nullFont);
    }

    _active_item = _right_btn_item;
    nullFont.setBold(true);
    _active_item->setFont(0,nullFont);          // 活动项目设置为粗体

}

void ProTreeWidget::SlotClosePro()
{
    RemoveProDialog remove_pro_dialog;
    auto result = remove_pro_dialog.exec();
    if(result != QDialog::Accepted){
        return ;
    }

    bool b_remove = remove_pro_dialog.ISRemoved();
    auto index_right_btn = this->indexOfTopLevelItem(_right_btn_item);      // 右键项的索引
    auto *protreeitem = dynamic_cast<ProTreeItem*>(_right_btn_item);        // 右键项
    auto *selecteditem = dynamic_cast<ProTreeItem*>(_selected_item);        // 选中项
    auto delete_path = protreeitem->GetPath();
    _set_path.remove(delete_path);          // 删除选中项的路径
    if(b_remove){           // 是否删除本地目录
        QDir delete_dir(delete_path);
        delete_dir.removeRecursively();     // 递归的删除
    }

    if(protreeitem == _active_item){        // 如果当前项和活动项相同，则把活动项置为空
        _active_item = nullptr;
    }

    if(selecteditem && protreeitem == selecteditem->GetRoot()){    // 判断选中项是否为空，右键项是否等于选中项的根节点
        selecteditem = nullptr;
        _selected_item = nullptr;                   // 当前选中项需要置为空，不然会出现bug，导致程序崩溃
        emit SigClearSelected();
    }

    delete this->takeTopLevelItem(index_right_btn);     // 把该目录从根目录树移除
    _right_btn_item = nullptr;
}

void ProTreeWidget::SlotDoubleClickItem(QTreeWidgetItem *doubleItem, int col)
{
    if(QGuiApplication::mouseButtons() == Qt::LeftButton){      // 点击的是否为左键
        auto *tree_doubleItem = dynamic_cast<ProTreeItem*>(doubleItem);
        if(!tree_doubleItem){
            return;
        }

        int itemtype = tree_doubleItem->type();
        if(itemtype == TreeItemPic){
            emit SigUpdateSelected(tree_doubleItem->GetPath());
            _selected_item = doubleItem;
        }
    }
}

void ProTreeWidget::SlotUpdateProgress(int count)
{
    if(!_dialog_progress){      // 判断进度条对话框是否为空
        return ;
    }

    if(count >= PROGRESS_MAX){
        _dialog_progress->setValue(count % PROGRESS_MAX);
    }else{
        _dialog_progress->setValue(count);
    }
}

void ProTreeWidget::SlotFinishProgress()
{
    if(_dialog_progress){   // 添加空指针检查
        _dialog_progress->setValue(PROGRESS_MAX);       // 完成时将进度条设置为最大
        _dialog_progress->deleteLater();
        _dialog_progress = nullptr; // 将指针置为空，避免悬空指针
    }
}

void ProTreeWidget::SlotCancelProgress()
{
    emit SigCancelProgress();       // 发出取消信号
    if(_dialog_progress){   // 添加空指针检查
        delete _dialog_progress;        // 删除对话框
        _dialog_progress = nullptr; // 将指针置为空，避免悬空指针
    }
}

void ProTreeWidget::SlotUpOpenProgress(int count)
{
    if(!_open_progressdlg){      // 判断进度条对话框是否为空
        return ;
    }

    if(count >= PROGRESS_MAX){
        _open_progressdlg->setValue(count % PROGRESS_MAX);
    }else{
        _open_progressdlg->setValue(count);
    }
}

void ProTreeWidget::SlotFinishOpenProgress()
{
    if(!_open_progressdlg){      // 判断进度条对话框是否为空
        return ;
    }

    _open_progressdlg->setValue(PROGRESS_MAX);
    delete _open_progressdlg;
    _open_progressdlg = nullptr;
}

void ProTreeWidget::SlotCancelOpenProgress()
{
    emit SigCancelOpenProgress();       // 发出取消信号
    if(_open_progressdlg){   // 添加空指针检查
        delete _open_progressdlg;        // 删除对话框
        _open_progressdlg = nullptr; // 将指针置为空，避免悬空指针
    }
}

void ProTreeWidget::SlotSlideShow()
{
    if(!_right_btn_item){       // 判断右键是否为空
        return ;
    }

    auto *right_pro_item = dynamic_cast<ProTreeItem*>(_right_btn_item);
    auto *last_child_item = right_pro_item->GetLastPicChild();
    if(!last_child_item){
        return ;
    }

    auto *first_child_item = right_pro_item->GetFirstPicChild();
    if(!first_child_item){
        return ;
    }

    // qDebug() << "first_child_item is" << first_child_item->GetPath();
    // qDebug() << "last_child_item is" << last_child_item->GetPath();
    _slide_show_dlg = std::make_shared<SlideShowDlg>(this, first_child_item, last_child_item);
    _slide_show_dlg->setModal(true);
    _slide_show_dlg->showMaximized();
}

void ProTreeWidget::SlotOpenPro(const QString &path)
{
    if(_set_path.find(path) != _set_path.end()){        // 判断项目是否已经打开
        return ;
    }

    _set_path.insert(path);     // 没有的话就加入到目录树中
    int file_count = 0;
    QDir pro_dir(path);
    QString proname = pro_dir.dirName();

    _thread_open_pro = std::make_shared<OpenTreeThread>(path, file_count, this, nullptr);       // 创建线程

    _open_progressdlg = new QProgressDialog(this);
    // 连接线程的信号域槽
    connect(_thread_open_pro.get(), &OpenTreeThread::SigUpdateProgress, this, &ProTreeWidget::SlotUpOpenProgress);   // 使用智能指针时需用get()方法取出真实类型

    connect(_thread_open_pro.get(), &OpenTreeThread::SigFinishProgress, this, &ProTreeWidget::SlotFinishOpenProgress);

    connect(_open_progressdlg, &QProgressDialog::canceled, this ,&ProTreeWidget::SlotCancelOpenProgress);

    connect(this, &ProTreeWidget::SigCancelOpenProgress, _thread_open_pro.get(), &OpenTreeThread::SlotCancelProgress);     // 通过线程

    _thread_open_pro->start();       // 启动线程
    _open_progressdlg->setWindowTitle("Please wait......");
    _open_progressdlg->setFixedWidth(PROGRESS_WIDTH);        // 固定为PROGRESS_WIDTH（300）
    _open_progressdlg->setRange(0,PROGRESS_WIDTH);       // 波动范围
    _open_progressdlg->exec();
}

void ProTreeWidget::SlotNextShow()
{
    if(!_selected_item){
        return;
    }

    auto *curItem = dynamic_cast<ProTreeItem*>(_selected_item)->GetNextItem();
    if(!curItem){
        return ;
    }

    emit SigUpdateSelected(curItem->GetPath());
    _selected_item = curItem;
    this->setCurrentItem(curItem);
}

void ProTreeWidget::SlotPreShow()
{
    if(!_selected_item){
        return;
    }

    auto *curItem = dynamic_cast<ProTreeItem*>(_selected_item)->GetPreItem();
    if(!curItem){
        return ;
    }

    emit SigUpdateSelected(curItem->GetPath());
    _selected_item = curItem;
    this->setCurrentItem(curItem);
}

void ProTreeWidget::SlotSetMusic()
{
    QFileDialog file_dialog;
    file_dialog.setFileMode(QFileDialog::ExistingFiles);
    file_dialog.setWindowTitle(tr("选择导入文件夹的文件"));
    file_dialog.setDirectory(QDir::currentPath());
    file_dialog.setViewMode(QFileDialog::Detail);
    file_dialog.setNameFilter("(*.mp3)");
    QStringList fileNames;
    if(file_dialog.exec()){
        fileNames = file_dialog.selectedFiles();
    }else{
        return ;
    }

    if(fileNames.length() <= 0){
        return ;
    }

    _playlist->clear();
    for(auto &filename: fileNames){
        _playlist->addMedia(QUrl::fromLocalFile(filename));
    }

    if(_player->state() != QMediaPlayer::PlayingState){         // 判断是否为播放状态
        _playlist->setCurrentIndex(0);
    }
}

void ProTreeWidget::SlotStartMusic()
{
    _player->play();
}

void ProTreeWidget::SlotStopMusic()
{
    _player->stop();
}
